package router

import (
	"errors"
	"net/http"
	"time"
	"web_framework/model"
	"web_framework/websocket/v1/handler"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	log "github.com/sirupsen/logrus"
)

var (
	upgrader = websocket.Upgrader{
		// 读取存储空间大小
		ReadBufferSize: 1024,
		// 写入存储空间大小
		WriteBufferSize: 1024,
		// 允许跨域
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
)

func init() {
	handler.Holder = &handler.ServiceHolder{
		make(map[int]handler.Service),
	}
	//注册服务
	handler.Holder.RegisterService(201, new(handler.RouterHeartHandle))
	handler.Holder.RegisterService(202, new(handler.AppHeartHandle))
	handler.Holder.RegisterService(207, new(handler.AppTaskNoticeHandle))
	handler.Holder.RegisterService(1, new(handler.RouterLoginHandle))
	handler.Holder.RegisterService(2, new(handler.AppLoginHandle))
	handler.Holder.RegisterService(1203, new(handler.TaskPushResponseHandle))
	handler.Holder.RegisterService(1204, new(handler.DelTaskPushResponseHandle))
	handler.Holder.RegisterService(210, new(handler.GetDeviceInfoHandle))
	handler.Holder.RegisterService(101, new(handler.GetRouterInfoHandle))
	handler.Holder.RegisterService(103, new(handler.GetTaskListHandle))
	handler.Holder.RegisterService(1212, new(handler.DelStorageFileHandle))
	handler.Holder.RegisterService(1209, new(handler.SetLimitSpeedHandle))
	handler.Holder.RegisterService(205, new(handler.RouterStorageOutNoticeHandle))
	handler.Holder.RegisterService(1105, new(handler.GetStorageParHandle))
	handler.Holder.RegisterService(1104, new(handler.GetSearchLocalHandle))
	handler.Holder.RegisterService(206, new(handler.AppStorageOutNoticeHandle))
}

func WsHand(c *gin.Context) {
	res := c.Writer
	req := c.Request
	if err := wsHandler(res, req); err != nil {
		return
	}
}

func wsHandler(w http.ResponseWriter, r *http.Request) (err error) {

	var (
		wsConn   *websocket.Conn
		conn     *handler.Connection
		clientId string
	)
	// 完成http应答，在httpheader中放下如下参数
	if wsConn, err = upgrader.Upgrade(w, r, nil); err != nil {
		return // 获取连接失败直接返回
	}

	if clientId, err = loginCheck(wsConn); err != nil {
		wsConn.Close()
		return
	}
	if conn, err = handler.InitConnection(wsConn, clientId); err != nil {
		return
	}

	handler.RouterMaps[clientId] = conn

	return
}

//对身份进行验证
func loginCheck(wsConn *websocket.Conn) (string, error) {
	ch := make(chan model.Request)
	defer close(ch)
	var data model.Request
	// 并发执行一个函数
	go func() {
		if err := wsConn.ReadJSON(&data); err != nil {
			log.Info(err.Error())
			wsConn.WriteMessage(1, []byte("login failed，connect closed："+err.Error()))
			wsConn.Close()
			return
		}
		ch <- data

	}()

	select {
	case <-ch:
		//登录信息验证
		clientId,err := handler.Holder.Login(data.Mtype, data, wsConn)
		if err != nil {
			log.Info(err.Error())
		}
		return clientId, err
	case <-time.After(10 * time.Second):
		err := errors.New("connect timeout")
		wsConn.WriteMessage(1, []byte("connect closed：login timeout"))
		return "", err
	}
}
